package com.the9tcat.deliverycoming.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.zip.GZIPInputStream;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.the9tcat.deliverycoming.modle.DeliveryDetail;
import com.the9tcat.deliverycoming.modle.DeliveryInfo;
import com.the9tcat.deliverycoming.modle.ParserDeliveryDetail;

// TODO: Auto-generated Javadoc
/**
 * The Class HttpClient.
 */
public class HttpClient {

	/** The instance. */
	private static HttpClient instance;

	/**
	 * New instance.
	 * 
	 * @return the operations
	 */
	public static HttpClient newInstance() {
		if (instance == null) {
			instance = new HttpClient();
			return instance;
		} else {
			return instance;
		}
	}
	
	public Bitmap checkValicode(DeliveryInfo d_info) {
		// 先看要不要验证码, 三步走战略！
		// 第一步，尝试获取信息
		String result = invokeService(d_info.getCompanyId(),
				d_info.getExpressNu(), null);
		try {
			JSONObject json = new JSONObject(result);
			int status = json.getInt("status");
			if (status == 2) {
				// 擦。。。估计要验证码
				Bitmap valicode = invokeValicode(d_info.getCompanyId());
				if (valicode != null) {
					result = invokeService(d_info.getCompanyId(),
							d_info.getExpressNu(), null);
					
					// 重复以上步骤(此步有疑问，至信委员长，先别删)
					json = new JSONObject(result);
					status = json.getInt("status");
					if (status == 2) {
						// 真正弹出验证码
						return invokeValicode(d_info.getCompanyId());
					}
				}
			}
		} catch (JSONException e1) {
			e1.printStackTrace();
		}
		return null;
	}

	/**
	 * Gets the deliveryDetails.
	 * 
	 * @param company
	 *            the company
	 * @param deliveryId
	 *            the delivery id
	 * @return the deliveryDetails
	 */
	public boolean updateDeliveryDetails(DeliveryInfo d_info, String valicode) {
		boolean update = false;
		if (d_info == null || d_info.getCompanyId() == null
				|| d_info.getCompanyId().equals("")
				|| null == d_info.getExpressNu()
				|| d_info.getExpressNu().equals("")) {
		} else {
			String result = invokeService(d_info.getCompanyId(),
					d_info.getExpressNu(), valicode);
			ArrayList<DeliveryDetail> details = null;
			if (result == null) {
			} else {
				try {
					details = ParserDeliveryDetail.getDeliveryDetails(result);
					int size = details.size();
					DeliveryDetail dd;
					for (int i = size - 1; i >= 0; i--) {
						dd = details.get(i);
						dd.setTrackId(d_info.getId());
						if (d_info.addDetail(dd)) {
							update = true;
						}
					}
					if (update) {
						d_info.setLatestStatus(details.get(0).getStatus());
						d_info.setLatestTime(details.get(0).getTime());
					}
				} catch (UnsupportedEncodingException e) {

				} catch (JSONException e) {

				}
			}
		}
		return update;
	}

	private Bitmap invokeValicode(String com) {
		try {
			HttpURLConnection huc = (HttpURLConnection) new URL(
					"http://api.kuaidi100.com/verifyCode?id=d2612e88759ac476&com=" + com)
					.openConnection();
			InputStream is = huc.getInputStream();
			if (is.available() != 0) {
				Bitmap b = BitmapFactory.decodeStream(is);
				return b;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * invoke JSON API.
	 * 
	 * @param com
	 *            the com
	 * @param nu
	 *            the nu
	 * @return the string
	 */
	private String invokeService(String com, String nu, String valicode) {
		// final String tag = "invokeWebService";
		if (com.equals("ems")) {
			if (nu.length() > 2) {
				nu = nu.substring(0, 2).toUpperCase()
						+ nu.substring(2).toLowerCase();
			}
		}
		org.apache.http.client.HttpClient httpClient = new DefaultHttpClient();

		String url = "http://www.kuaidi100.com/api?id=d2612e88759ac476&show=0&muti=1&com="
				+ com + "&nu=" + nu;

		if (valicode != null) {
			url += "&valicode=" + valicode;
		}

		HttpGet httpGet = null;
		try {
			httpGet = new HttpGet(url);
		} catch (Exception e) {

		}
		if (httpGet == null) {
			return "";
		}

		// Request GZip format
		httpGet.addHeader("Accept-Encoding", "gzip");

		String responseStr = "";
		HttpResponse response;
		try {
			response = httpClient.execute(httpGet);
			// StatusLine status = response.getStatusLine();

			HttpEntity entity = response.getEntity();
			InputStream content = entity.getContent();

			// Try to get content by gzip
			Header header = entity.getContentEncoding();
			if (header != null && header.getValue().contains("gzip")) {
				responseStr = getStringFromZip(content);
			} else {
				responseStr = convertInputStreamToString(content);
			}
			content.close();

		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// if (Utility.ENABLED && responseStr != null) {
		// Utility.log(tag, responseStr);
		// }
		return responseStr;

	}

	/**
	 * Convert input stream to string.
	 * 
	 * @param is
	 *            the is
	 * @return the string
	 */
	private String convertInputStreamToString(InputStream is) {
		final BufferedReader bf = new BufferedReader(new InputStreamReader(is));

		String tempString = null;
		final StringBuilder sb = new StringBuilder();
		try {
			while ((tempString = bf.readLine()) != null) {
				sb.append(tempString);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				is.close();
				bf.close();
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
		}
		return sb.toString();
	}

	/**
	 * decompress the stream.
	 * 
	 * @param is
	 *            the is
	 * @return the string from zip
	 * @throws IOException
	 *             Signals that an I/O exception has occurred.
	 */
	private String getStringFromZip(InputStream is) throws IOException {
		InputStream gzin = new GZIPInputStream(is);
		InputStreamReader isr = new InputStreamReader(gzin, "utf-8");
		java.io.BufferedReader br = new java.io.BufferedReader(isr);
		String tempbf;
		StringBuffer sb = new StringBuffer();
		while ((tempbf = br.readLine()) != null) {
			sb.append(tempbf);
		}
		isr.close();
		gzin.close();
		return sb.toString();
	}
}
